package cn.matezk.lianlian.task;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.matezk.lianlian.beans.Constant;
import cn.matezk.lianlian.dao.DeviceDao;
import cn.matezk.lianlian.dao.NotifyRecordDao;
import cn.matezk.lianlian.framework.RedisMutexLock;
import cn.matezk.lianlian.model.Device;
import cn.matezk.lianlian.model.NotifyRecord;
import cn.matezk.lianlian.model.NotifyTemplate;
import com.aliyun.sdk.service.dyvmsapi20170525.AsyncClient;
import com.aliyun.sdk.service.dyvmsapi20170525.models.QueryCallDetailByCallIdRequest;
import com.aliyun.sdk.service.dyvmsapi20170525.models.QueryCallDetailByCallIdResponse;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@Component
public class TTSSyncTask {
    @Autowired
    private NotifyRecordDao notifyRecordDao;
    @Autowired
    private DeviceDao deviceDao;
    @Autowired
    private RedisMutexLock mutexLock;
    @Autowired
    private AsyncClient client;

    private static final String LOCK_KEY = "lock.voice";

    private static List<String> successStates = new ArrayList<>();
    private static List<String> failedStates = new ArrayList<>();
    static {
        successStates.add("200000");
        successStates.add("200001");
        successStates.add("200103");

        failedStates.add("200002");
        failedStates.add("200003");
        failedStates.add("200004");
        failedStates.add("200005");
        failedStates.add("200006");
        failedStates.add("200007");
        failedStates.add("200010");
        failedStates.add("200011");
        failedStates.add("200104");
        failedStates.add("200105");
        failedStates.add("200111");
        failedStates.add("200120");
        failedStates.add("200121");
        failedStates.add("200112");
        failedStates.add("200116");
        failedStates.add("200118");
        failedStates.add("200119");
        failedStates.add("999999");
        failedStates.add("500");
        failedStates.add("400");
        failedStates.add("482");
        failedStates.add("476");
    }

    @XxlJob("ttsSyncTask")
    public void execute() {
        if (!mutexLock.lock(LOCK_KEY, 1000 * 60))   return;
        XxlJobHelper.log("同步语音发送状态任务开始执行");
        try {
            List<NotifyRecord> records = notifyRecordDao.selectWaitNotifyByMethod(NotifyTemplate.METHOD_VOICE);
            if (ObjectUtil.isEmpty(records)) return;
            for (NotifyRecord record : records) {
                if (!NotifyRecord.STATUS_CONFIRM.equals(record.getStatus()))
                    continue;
                QueryCallDetailByCallIdRequest request = QueryCallDetailByCallIdRequest.builder()
                        .callId(record.getBizId())
                        .prodId(11000000300006L)
                        .queryDate(record.getNotifyTime().getTime()).build();
                try {
                    CompletableFuture<QueryCallDetailByCallIdResponse> future = client.queryCallDetailByCallId(request);
                    QueryCallDetailByCallIdResponse response = future.get();
                    XxlJobHelper.log(JSONUtil.toJsonStr(response));
                    if (!response.getBody().getCode().equals("OK"))
                        continue;
                    JSONObject payload = JSONUtil.parseObj(response.getBody().getData());
                    String state = payload.getStr("state");
                    if (successStates.contains(state) || failedStates.contains(state)) {
                        String notifyLockKey = NotifyRecord.createLockKey(record.getBizId());
                        if (mutexLock.tryLock(notifyLockKey, 3)) {
                            try {
                                record.setStatus(successStates.contains(state) ? NotifyRecord.STATUS_SUCCESS : NotifyRecord.STATUS_FAILED);
                                int count = notifyRecordDao.updateByBizId(record);
                                if (count > 0 && failedStates.contains(state)) {
                                    String deviceLockKey = Device.createLockKey(record.getDeviceId());
                                    if (mutexLock.tryLock(deviceLockKey, 3)) {
                                        try {
                                            Device device = deviceDao.selectByPrimaryKey(record.getDeviceId());
                                            deviceDao.updateAmount(device.getDeviceId(), device.getAmount() + Constant.TTS_UNIT_PRICE);
                                        } finally {
                                            mutexLock.unlock(deviceLockKey);
                                        }
                                    }
                                }
                            } finally {
                                mutexLock.unlock(notifyLockKey);
                            }
                        }
                    }
                } catch (Exception e) {
                    XxlJobHelper.log(e);
                    continue;
                }
            }
        } catch (Exception e) {
            XxlJobHelper.log(e);
        } finally {
            XxlJobHelper.log("同步语音发送状态任务执行完毕");
            mutexLock.unlock(LOCK_KEY);
        }
    }
}
